package main

import (
	"flag"
	"gitee.com/baal1990/gitee.com/baal1990/pkg/crypto"
	"io/ioutil"
	"log"
	"strings"
)

var (
	Asymmetric    = make(map[string]crypto.AsymmetricCrypto)
	CryptoType    = ""
	CryptoKeyFile = ""
	CryptoMethod  = ""
	CryptoSign    = ""
	Data          = ""
	GenKey        = ""
)

func initCrypto() {
	Asymmetric["sm2"] = crypto.SM2{}
}

func main() {
	flag.StringVar(&GenKey, "gen-key", "", "key path")
	flag.StringVar(&CryptoType, "type", "", "sm2")
	flag.StringVar(&CryptoKeyFile, "key", "", "pub.pem/priv.pem")
	flag.StringVar(&CryptoMethod, "method", "", "encrypt/decrypt/sign/verify")
	flag.StringVar(&Data, "data", "", "")
	flag.StringVar(&CryptoSign, "sign", "", "")
	flag.Parse()

	initCrypto()
	CryptoType = strings.ToLower(CryptoType)
	CryptoMethod = strings.ToLower(CryptoMethod)
	crypto, ok := Asymmetric[CryptoType]
	if !ok {
		log.Printf("invalid type, [%s]\n", CryptoType)
		log.Println("run --help")
		return
	}
	if GenKey != "" {
		pub := GenKey + "/pub.hex"
		priv := GenKey + "/priv.hex"
		if err := crypto.GenerateKey(pub, priv); err != nil {
			log.Printf("GenerateKey fail, %v\n", err)
			return
		}
	} else {
		keyPem, err := ioutil.ReadFile(CryptoKeyFile)
		if err != nil {
			log.Printf("invalid key, %v\n", err)
			return
		}
		// 处理
		switch CryptoMethod {
		case "encrypt":
			base64Code, err := crypto.EncryptWithBase64([]byte(Data), keyPem)
			if err != nil {
				log.Printf("%s %s fail, %v\n", CryptoType, CryptoMethod, err)
				return
			}
			log.Printf("raw    = [%s]\n", Data)
			log.Printf("crypto = [%s]\n", base64Code)
		case "decrypt":
			raw, err := crypto.DecryptWithBase64(Data, keyPem)
			if err != nil {
				log.Printf("%s %s fail, %v\n", CryptoType, CryptoMethod, err)
				return
			}
			log.Printf("crypto = [%s]\n", Data)
			log.Printf("raw    = [%s]\n", raw)
		case "sign":
			base64Code, err := crypto.SignWithBase64([]byte(Data), keyPem)
			if err != nil {
				log.Printf("%s %s fail, %v\n", CryptoType, CryptoMethod, err)
				return
			}
			log.Printf("raw  = [%s]\n", Data)
			log.Printf("sign = [%s]\n", base64Code)
		case "verify":
			result, err := crypto.VerifyWithBase64([]byte(Data), keyPem, CryptoSign)
			if err != nil {
				log.Printf("%s %s fail, %v\n", CryptoType, CryptoMethod, err)
				return
			}
			if result {
				log.Println("verify success")
			} else {
				log.Println("verify fail")
			}
		default:
			log.Println("run --help")
		}
	}
}
